﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using DoubleH.Utility.Configuration;
using Table = FCNS.Data.Interface;
using System.Collections;

namespace DoubleH.Utility.UC
{
    /// <summary>
    /// UCDateTime.xaml 的交互逻辑
    /// </summary>
    public partial class UCDateTime : UserControl
    {
        public UCDateTime()
        {
            InitializeComponent();

            if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
                return;

            InitEvent();
            InitVar();
        }

        private void InitVar()
        {
            gridFilter.Visibility = (canFilterByDate ? Visibility.Visible : Visibility.Collapsed);
            comboBoxDate.SelectedIndex = 3;
            comboBoxType.SelectedIndex = 2;
        }

        private void InitEvent()
        {
            comboBoxDate.SelectionChanged += (ss, ee) => SetDateTime();
            comboBoxType.SelectionChanged += (ss, ee) => ChangeType();
            dateTimePickerEnd.ValueChanged += (ss, ee) => IsDateTimeOK();
        }

        private void IsDateTimeOK()
        {
            if (dateTimePickerEnd.Value.Value < dateTimePickerStart.Value.Value)
            {
                MessageWindow.Show("结束日期不能小于开始日期");
                dateTimePickerEnd.Value = dateTimePickerStart.Value;
            }
        }

        private void ChangeType()
        {
            intergerUpDownDay.IsEnabled = (comboBoxType.SelectedIndex == comboBoxType.Items.Count - 1);
        }

        private void SetDateTime()
        {
            string start = "19840924" + DoubleHConfig.UserConfig.WorkStart;
            string end = "19890615" + DoubleHConfig.UserConfig.WorkEnd;
            switch (comboBoxDate.SelectedIndex)
            {
                case 0:
                    start = DateTime.Now.ToString("yyyyMMdd") + DoubleHConfig.UserConfig.WorkStart;
                    end = DateTime.Now.ToString("yyyyMMdd") + DoubleHConfig.UserConfig.WorkEnd;
                    break;
                case 1:
                    start = DateTime.Now.AddDays((DateTime.Now.DayOfWeek == DayOfWeek.Sunday ? -6 : 1 - (int)DateTime.Now.DayOfWeek)).ToString("yyyyMMdd") + DoubleHConfig.UserConfig.WorkStart;
                    end = DateTime.Now.AddDays((DateTime.Now.DayOfWeek == DayOfWeek.Sunday ? 0 : 7 - (int)DateTime.Now.DayOfWeek)).ToString("yyyyMMdd") + DoubleHConfig.UserConfig.WorkEnd;
                    break;
                case 2:
                    start = DateTime.Now.AddDays((DateTime.Now.DayOfWeek == DayOfWeek.Sunday ? -13 : -6 - (int)DateTime.Now.DayOfWeek)).ToString("yyyyMMdd") + DoubleHConfig.UserConfig.WorkStart;
                    end = DateTime.Now.AddDays((DateTime.Now.DayOfWeek == DayOfWeek.Sunday ? -7 : 0 - (int)DateTime.Now.DayOfWeek)).ToString("yyyyMMdd") + DoubleHConfig.UserConfig.WorkEnd;
                    break;
                case 3:
                    start = DateTime.Now.AddDays(1 - DateTime.Now.Day).ToString("yyyyMMdd") + DoubleHConfig.UserConfig.WorkStart;
                    end = DateTime.Now.AddDays(DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month) - DateTime.Now.Day).ToString("yyyyMMdd") + DoubleHConfig.UserConfig.WorkEnd;
                    break;
                case 4:
                    int m = DateTime.Now.Month;
                    start = DateTime.Now.AddMonths(-1).ToString("yyyyMM") + "01" + DoubleHConfig.UserConfig.WorkStart;
                    end = DateTime.Now.AddMonths(-1).ToString("yyyyMM") + DateTime.DaysInMonth(DateTime.Now.AddMonths(-1).Year, DateTime.Now.AddMonths(-1).Month) + DoubleHConfig.UserConfig.WorkEnd;
                    break;
                case 5:
                    start = DateTime.Now.Year.ToString() + "0101" + DoubleHConfig.UserConfig.WorkStart;
                    end = DateTime.Now.Year.ToString() + "12" + DateTime.DaysInMonth(DateTime.Now.Year, 12).ToString() + DoubleHConfig.UserConfig.WorkEnd;
                    break;
            }

            dateTimePickerStart.Value = DateTime.ParseExact(start, FCNS.Data.DbDefine.dateTimeFormat, null);
            dateTimePickerEnd.Value = DateTime.ParseExact(end, FCNS.Data.DbDefine.dateTimeFormat, null);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj">此值必须集成 IOrder 接口</param>
        /// <returns></returns>
        public Dictionary<string, List<object>> FilterData(IList obj)
        {
            if (!canFilterByDate || obj == null || obj.Count == 0)
                return null;

            Sort(obj);

            switch (comboBoxType.SelectedIndex)
            {
                case 0: return FilterByYear(obj);
                case 1: return FilterByMonth(obj);
                case 2: return FilterByWeek(obj);
                default: return FilterByDay(obj);
            }
        }

        private Dictionary<string, List<object>> FilterByYear(IList obj)
        {
            Dictionary<string, List<object>> result = new Dictionary<string, List<object>>();
            DateTime firstDate = ((Table.IOrder)obj[0]).OrderDateTime;
            DateTime endDate = ((Table.IOrder)obj[obj.Count - 1]).OrderDateTime;

            for (int i = 0; i <= endDate.Year - firstDate.Year; i++)
            {
                int year = firstDate.Year + i;
                List<object> li = new List<object>();
                foreach (Table.IOrder order in obj)
                    if (order.OrderDateTime.Year == year)
                        li.Add(order);

                result.Add(year.ToString(), li);
            }
            return result;
        }

        private Dictionary<string, List<object>> FilterByMonth(IList obj)
        {
            Dictionary<string, List<object>> result = new Dictionary<string, List<object>>();
            DateTime firstDate = ((Table.IOrder)obj[0]).OrderDateTime;
            DateTime endDate = ((Table.IOrder)obj[obj.Count - 1]).OrderDateTime;
            int month = GetAllMonth(firstDate, endDate);

            for (int i = 0; i < month+1; i++)
            {
                DateTime date = firstDate.AddMonths(i);
                List<object> li = new List<object>();
                foreach (Table.IOrder order in obj)
                    if (order.OrderDateTime.Year == date.Year && order.OrderDateTime.Month == date.Month)
                        li.Add(order);

                result.Add(date.ToString("yyyy-MM"), li);
            }
            return result;
        }
        //星期一到星期日
        private Dictionary<string, List<object>> FilterByWeek(IList obj)
        {
            Dictionary<string, List<object>> result = new Dictionary<string, List<object>>();
            DateTime firstDate = ((Table.IOrder)obj[0]).OrderDateTime;
            DateTime endDate = ((Table.IOrder)obj[obj.Count - 1]).OrderDateTime;
            int allDay = GetAllDay(firstDate, endDate);

            //添加开始
            int startDayNeedDay =7-  (int)firstDate.DayOfWeek;
            //如果天数不够一个星期
            if (allDay < (int)firstDate.DayOfWeek)
            {
                result.Add(firstDate.ToString("yyyy-MM-dd") + " - " + firstDate.AddDays(allDay).ToString("yyyy-MM-dd"),
                    GetList(obj, firstDate, firstDate.AddDays(allDay)));

                return result;
            }
            else
            {
                result.Add(firstDate.ToString("yyyy-MM-dd") + " - " + firstDate.AddDays(startDayNeedDay).ToString("yyyy-MM-dd"),
                      GetList(obj, firstDate, firstDate.AddDays(startDayNeedDay)));
                //添加中间
                int endDayNeedDay = (endDate.DayOfWeek == DayOfWeek.Sunday ? -6 : -((int)endDate.DayOfWeek - 1));
                for (int i = 7; i <= allDay - startDayNeedDay - endDayNeedDay - 2; i += 7)
                {
                    DateTime f = firstDate.AddDays(startDayNeedDay + i - 6);
                    DateTime e = f.AddDays(6);
                    result.Add(f.ToString("yyyy-MM-dd") + " - " + e.ToString("yyyy-MM-dd"), GetList(obj, f, e));
                }
                //添加最后
                result.Add(endDate.AddDays(endDayNeedDay).ToString("yyyy-MM-dd") + " - " + endDate.ToString("yyyy-MM-dd"),
                        GetList(obj, endDate.AddDays(endDayNeedDay), endDate));
            }
            return result;
        }

        private Dictionary<string, List<object>> FilterByDay(IList obj)
        {
            Dictionary<string, List<object>> result = new Dictionary<string, List<object>>();
            DateTime firstDate = ((Table.IOrder)obj[0]).OrderDateTime;
            DateTime endDate = ((Table.IOrder)obj[obj.Count - 1]).OrderDateTime;
            int allDay = GetAllDay(firstDate, endDate);

            for (int i = 0; i < allDay; i += intergerUpDownDay.Value.Value  )
            {
                DateTime f = firstDate.AddDays(i);
                DateTime e = firstDate.AddDays(i + intergerUpDownDay.Value.Value-1);
                result.Add(f.ToString("yyyy-MM-dd - ") + e.ToString("yyyy-MM-dd"),
                    GetList(obj, f, e));
            }
            return result;
        }
        //只验证日期不验证时间
        private List<object> GetList(IList obj, DateTime start, DateTime end)
        {
            List<object> li = new List<object>();
            foreach (Table.IOrder order in obj)
                if (order.OrderDateTime.Date >= start.Date && order.OrderDateTime.Date <= end.Date)
                    li.Add(order);

            return li;
        }

        private int GetAllMonth(DateTime firstDate, DateTime endDate)
        {
          return (endDate.Year - firstDate.Year) * 12 + endDate.Month - firstDate.Month ;
        }

        private int GetAllDay(DateTime firstDate, DateTime endDate)
        {
            int month = GetAllMonth(firstDate, endDate);
            if (month == 0)
                return endDate.Day - firstDate.Day + 1;
            else
            {
                int allDay = DateTime.DaysInMonth(firstDate.Year, firstDate.Month) - firstDate.Day + 1 + endDate.Day;//首月+尾月
                for (int i = 1; i < month; i++)
                {
                    DateTime temp = firstDate.AddMonths(i);
                    allDay += DateTime.DaysInMonth(temp.Year, temp.Month);
                }
                return allDay;
            }
        }

        private void Sort(IList obj)
        {
            int count = obj.Count;
            for (int i = 0; i < count; i++)
            {
                for (int j = i + 1; j < count; j++)
                {
                    if (((Table.IOrder)obj[i]).OrderDateTime > ((Table.IOrder)obj[j]).OrderDateTime)
                    {
                        object temp = obj[i];
                        obj[i] = obj[j];
                        obj[j] = temp;
                    }
                }
            }
        }

        bool canFilterByDate = false;
        /// <summary>
        /// 是否使用 日期 筛选数据
        /// </summary>
        public bool CanFilterByDate
        {
            get { return canFilterByDate; }
            set
            {
                canFilterByDate = value;
                gridFilter.Visibility = (value ? Visibility.Visible : Visibility.Collapsed);
            }
        }

        public DateTime StartDateTime
        {
            get { return dateTimePickerStart.Value.Value; }
        }

        public string StartDateTimeString
        {
            get { return StartDateTime.ToString(FCNS.Data.DbDefine.dateTimeFormat); }
        }

        public DateTime EndDateTime
        {
            get { return dateTimePickerEnd.Value.Value; }
        }

        public string EndDateTimeString
        {
            get { return EndDateTime.ToString(FCNS.Data.DbDefine.dateTimeFormat); }
        }
    }
}